using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Threading;

namespace Dida.Test
{
	public static class Assert
	{
		static int debugAssertUserCount = 0;
		static UnitTestTraceListener traceListener = new UnitTestTraceListener();

		internal static void AddUser()
		{
			lock (traceListener)
			{
				if (debugAssertUserCount == 0)
				{
					Debug.Listeners.Insert(0, traceListener);
				}

				debugAssertUserCount++;
			}
		}

		internal static void RemoveUser()
		{
			lock (traceListener)
			{
				debugAssertUserCount--;

				if (debugAssertUserCount == 0)
				{
					Debug.Listeners.Remove(traceListener);
				}
			}
		}

		private class UnitTestTraceListener : TraceListener
		{
			public override void Write(string message)
			{
			}

			public override void WriteLine(string message)
			{
			}

			public override void Fail(string message)
			{
				//if (TestThread.AreWeInATestThread)
				{
					Assert.Fail();
				}
			}

			public override void Fail(string message, string detailMessage)
			{
				//if (TestThread.AreWeInATestThread)
				{
					Assert.Fail();
				}
			}
		}

		public static void Fail()
		{
			Thread.CurrentThread.Abort(null);
		}

		public static void Fail(string msg)
		{
			Thread.CurrentThread.Abort(msg);
		}

		public static void IsTrue(bool condition)
		{
			if (!condition)
			{
				Fail();
			}
		}

		public static void IsTrue(bool condition, string message)
		{
			if (!condition)
			{
				Fail(message);
			}
		}

		public static void Equal<T>(T a, T b)
		{
			Debug.Assert(a.Equals(b), "Test failed");
		}

		public static void FloatsEqual(float a, float b)
		{
			FloatsEqual(a, b, .001f);
		}

		public static void FloatsEqual(float a, float b, float threshold)
		{
			float diff = a - b;
			IsTrue(diff > -threshold && diff < threshold);
		}

		public static void FloatsEqual(float a, float b, string message)
		{
			FloatsEqual(a, b, .001f, message);
		}

		public static void FloatsEqual(float a, float b, float threshold, string message)
		{
			float diff = a - b;
			IsTrue(diff > -threshold && diff < threshold, message);
		}
	}
}
